package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.pojo.PageResult;
import com.leyou.item.mapper.*;
import com.leyou.item.pojo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

;

/**
 * *
 * Created by IntelliJ IDEA.
 * Author: caoLei
 * Date: 2018/10/25
 * Time: 20:00
 * *
 */

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 根据关键字分页查询spu
     * @param key
     * @param saleable
     * @param page
     * @param rows
     * @return
     */
    public PageResult<SpuBo> querySpuByPage(String key, Boolean saleable, Integer page, Integer rows) {

        //查询spu
        //分页（使用分页助手），
        PageHelper.startPage(page, rows);

        //创造查询条件
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();

        //是否过滤上下架
        if (saleable != null) {
            criteria.orEqualTo("saleable", saleable);
        }

        //是否模糊查询
        if (StringUtils.isNotBlank(key)) {
            //根据spu表中字段（title）进行模糊查询
            criteria.andLike("title", "%" + key + "%");
        }

        //查询结果集
        List<Spu> spus = this.spuMapper.selectByExample(example);

        PageInfo<Spu> pageInfo = new PageInfo<>(spus);

        //处理成spubo
        List<SpuBo> spuBos = spus.stream().map(spu -> {
//根据brandId查新brand
            Brand brand = this.brandMapper.selectByPrimaryKey(spu.getBrandId());
            //根据分类id查询分类
            List<String> names = this.categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            SpuBo spuBo = new SpuBo();
            BeanUtils.copyProperties(spu, spuBo);

            spuBo.setBname(brand.getName());
            spuBo.setCname(StringUtils.join(names, "-"));
            return spuBo;

        }).collect(Collectors.toList());
        return new PageResult<>(pageInfo.getTotal(), spuBos);

    }

    /**
     * 新增商品
     * @param spuBo
     */
    @Transactional  //增加事务
    public void saveGoods(SpuBo spuBo) {

        //保存spu
        spuBo.setSaleable(true);
        spuBo.setValid(true);
        spuBo.setCreateTime(new Date());
        spuBo.setLastUpdateTime(spuBo.getCreateTime());
        this.spuMapper.insertSelective(spuBo);


        //保存spuDetail
        SpuDetail spuDetail = spuBo.getSpuDetail();
        spuDetail.setSpuId(spuBo.getId());  //我们先在spu表中插入数据，接下来在spudetail表中插入数据，我们需要根据spu表的spuid，来插入spudetailid（它们是一样的）
        this.spuDetailMapper.insertSelective(spuDetail); //这里传的是spuDetail，但是不能直接get获得，而我们在spuBo里集成了spuDetail
        saveSkuAndStock(spuBo);


        sendMessage(spuBo.getId(),"insert");

    }

    /**
     * 发送消息（spuID）
     * @param spuID
     */
    private void sendMessage(Long spuID,String type) {
        try {
            this.amqpTemplate.convertAndSend("item."+type,spuID);
        } catch (AmqpException e) {
            e.printStackTrace();
        }
    }


    public SpuDetail querySpuDetailById(Long spuId) {
        return this.spuDetailMapper.selectByPrimaryKey(spuId);
    }

    public List<Sku> querySkusBySpuId(Long spuId) {
        //查询sku
        Sku record = new Sku();
        record.setSpuId(spuId);
        List<Sku> skus = this.skuMapper.select(record);
        for (Sku sku : skus) {
            //同时查询出库存
            Stock stock = this.stockMapper.selectByPrimaryKey(sku.getId());
            sku.setStock(stock.getStock());
        }
        return skus;
    }


    /**
     * 修改后保存商品
     * @param spuBo
     */
    @Transactional
    public void updateGoods(SpuBo spuBo) {
        //查询spu下的所有sku
        Sku record = new Sku();
        record.setSpuId(spuBo.getId());
        List<Sku> skus = this.skuMapper.select(record);
        //根据skuid删除所有sku的库存信息
        for (Sku sku : skus) {
            this.stockMapper.deleteByPrimaryKey(sku.getId());
        }

        //删除sku
        Sku sku = new Sku();
        sku.setSpuId(spuBo.getId());
        this.skuMapper.delete(sku);

        //更新spu和spuDetail
        spuBo.setLastUpdateTime(new Date());
        spuBo.setSaleable(true);  //显示上架
        spuBo.setValid(true);  //有效数据
        this.spuMapper.updateByPrimaryKeySelective(spuBo);

        //新增sku和stock
        saveSkuAndStock(spuBo);

        sendMessage(spuBo.getId(),"update");

    }

    //抽取的方法
    private void saveSkuAndStock(SpuBo spuBo) {
        //保存sku
        List<Sku> skus = spuBo.getSkus();
        //循环遍历skus
        for (Sku sku : skus) {

            sku.setSpuId(spuBo.getId());  //spuBo.getId()==spuId;
            // sku本身的id是自增长的，所以我们插入数据的时候，只要插入要新增的数据即可，这里需要spuId(可从表的对象信息中查看)
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            this.skuMapper.insertSelective(sku);

            //保存stock
            Stock stock = new Stock();
            stock.setStock(sku.getStock());
            stock.setSkuId(sku.getId());
            this.stockMapper.insertSelective(stock);
        }
    }

    public Spu querySpuBySpuId(Long spuId) {
        return this.spuMapper.selectByPrimaryKey(spuId);
    }


    /**
     * 根据skuid查询sku
     * @param
     * @return
     */
    public Sku querySkuById(Long skuId) {
        return this.skuMapper.selectByPrimaryKey(skuId);
    }
}
